/**
 *  Stream Recorder: Records RealPlayer(tm) streams as MP3s
 *  Copyright (C) 2007  David Griffiths
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

package dg.radio2ipod.view;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
import dg.radio2ipod.model.Stream;

/**
 *
 * @author davidg
 */
public final class StreamCellRenderer implements ListCellRenderer {
    static final int TOP_MARGIN = 3;
    static final int BOTTOM_MARGIN = 4;
    static final int LEFT_MARGIN = 14;
    static final int RIGHT_MARGIN = 14;
    static final Font SYSTEM_FONT = new Font("Lucida Grande",
            Font.PLAIN, 13);
    static final Font ENHANCED_SYSTEM_FONT = new Font("Lucida Grande",
            Font.BOLD, 13);
    static final Font SMALL_SYSTEM_FONT = new Font("Lucida Grande",
            Font.PLAIN, 9);

    /**
     * Creates a new instance of StreamCellRenderer.
     */
    public StreamCellRenderer() {
    }

    public Component getListCellRendererComponent(final JList list,
            final Object value, final int index, final boolean isSelected,
            final boolean cellHasFocus) {
        return new JComponent() {
            private Image imgDelete;

            public Dimension getPreferredSize() {
                Stream stream = (Stream) value;
                Font titleFont = null;
                if (stream.getStatus() == Stream.UNSTARTED) {
                    titleFont = SYSTEM_FONT;
                } else {
                    titleFont = ENHANCED_SYSTEM_FONT;
                }
                FontMetrics fmTitle = getFontMetrics(titleFont);
                FontMetrics fmSource = getFontMetrics(SMALL_SYSTEM_FONT);
                int y = TOP_MARGIN + fmTitle.getAscent();
                y += fmTitle.getDescent() + fmSource.getAscent();
                y += fmSource.getDescent() + fmSource.getAscent();
                y += fmSource.getDescent() + BOTTOM_MARGIN;
                int h = y;
                int w = LEFT_MARGIN + RIGHT_MARGIN;
                int x = 0;
                if (stream.getTitle() != null) {
                    x = fmTitle.stringWidth(stream.getTitle());
                }
                if (stream.getArtist() != null) {
                    x = Math.max(x, fmSource.stringWidth(stream.getArtist()));
                }
                if (stream.getSource() != null) {
                    x = Math.max(x, fmSource.stringWidth(stream.getSource()));
                }
                w += x;
                int deleteImageWidth = 12;
                w += deleteImageWidth;
                return new Dimension(w, h);
            }

            public void paintComponent(final Graphics g) {
                Dimension dim = getSize();
                if (index % 2 == 0) {
                    g.setColor(new Color(248, 248, 255));
                    g.fillRect(0, 0, dim.width, dim.height);
                } else {
                    g.setColor(Color.white);
                    g.fillRect(0, 0, dim.width, dim.height);
                }
                if (!(value instanceof Stream)) {
                    throw new RuntimeException(value + " is not a stream");
                }
                Stream stream = (Stream) value;
                Color colour = Color.black;
                if (stream.getStatus() == Stream.UNSTARTED) {
                    colour = Color.gray;
                }
                g.setColor(colour);
                if (stream.getStatus() == Stream.UNSTARTED) {
                    g.setFont(SYSTEM_FONT);
                } else {
                    g.setFont(ENHANCED_SYSTEM_FONT);
                }
                FontMetrics fmTitle = getFontMetrics(g.getFont());

                int y = TOP_MARGIN + fmTitle.getAscent();

                g.drawString(stream.getTitle() + " " + stream.getStatusDesc(),
                        LEFT_MARGIN, y);

                g.setFont(SMALL_SYSTEM_FONT);
                FontMetrics fmSource = getFontMetrics(g.getFont());

                y += fmTitle.getDescent() + fmSource.getAscent();

                if (stream.getArtist() != null) {
                    g.drawString(stream.getArtist(), LEFT_MARGIN, y);
                }

                y += fmSource.getDescent() + fmSource.getAscent();

                if (stream.getSource() != null) {
                    g.drawString(stream.getSource(), LEFT_MARGIN, y);
                }

                if (imgDelete == null) {
                    String cross = "/dg/radio2ipod/resource/cross_12x12.png";
                    java.net.URL url = getClass().getResource(cross);
                    if (url == null) {
                        throw new RuntimeException("Unable to find picture "
                                + cross);
                    }
                    imgDelete = Toolkit.getDefaultToolkit().getImage(url);
                    loadImage(imgDelete);
                }
                g.drawImage(imgDelete, dim.width - RIGHT_MARGIN - 12,
                        (dim.height - 12) / 2, this);
            }

            private void loadImage(final Image image) {
                MediaTracker mediaTracker = new MediaTracker(this);
                mediaTracker.addImage(image, 0);
                try {
                    mediaTracker.waitForID(0);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return;
            }
        };
    }

}
